import Cocoa

//var str = "Hello, playground"

//枚举的语法
enum compassPoint {
    case east
    case west
    case north
    case south
}
//也可以一次定义多个枚举变量,使用 逗号(,) 隔开
enum compassPoint2 {
    case east, west, north, south
}

//可以使用switch语句来匹配每一个单独的枚举值
let directionToHead = compassPoint.north
switch directionToHead {
case .east:
    print("east")
case .west:
    print("west")
case .north:
    print("north")
case .south:
    print("south")
//default:
//    <#code#>
}

//遍历枚举的case:在定义枚举的时候加上关键字CaseInterable
enum compassPoint3: CaseIterable {
    case east
    case west
    case north
    case south
}

////可以在枚举名后点出allCases然后点出count获取这个枚举有多少个case
let count = compassPoint3.allCases.count
print("count is \(count)")

//也可以遍历整个枚举
for direction in compassPoint3.allCases {
    print("direction is \(direction)")
}

//使用Swift定义枚举来存储任意给定类型的关联值
enum barCode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}
var productCode = barCode.upc(1, 2, 234, 876)
print("productCode is \(productCode)")
productCode = .qrCode("ERTVGJHJGHBKJ")
print("productCode is \(productCode)")

//匹配单独的枚举值
switch productCode {
case .upc(let numbersystem, let manufactor, let product, let check):
    print("UPC is \(numbersystem), \(manufactor), \(product), \(check)")
case .qrCode(let productCoed):
    print("qrcode is \(productCoed)")
}

//枚举也可以有原始值
enum controlCharacter: Character {
    case tab = "\t"
    case linefeed = "\n"
    case carrigeReturn = "\r"
}
print(controlCharacter.linefeed.rawValue)  //输出结果是换行了

//预设原始值:预设west等于5,那么后面的值依次往后面加1
enum point: Int {
    case west = 5
    case north   // 6
    case east    // 7
    case south   // 8
}
print(point.south.rawValue)   //输出结果为:8

//也可以使用rawValue来创建或者初始化一个枚举值,最终可以获取枚举的具体值
let direction2 = point(rawValue: 9)
print(direction2 ?? 0)   //如果direction2没有值的话,默认就是0


//递归枚举:需要在枚举前声明indirect关键字来明确他是递归的
//indirect:间接的,迂回的,非直截了当的
indirect enum ArithmeticExpression {
    case number(Int)
    case add(ArithmeticExpression, ArithmeticExpression)
    case multiply(ArithmeticExpression, ArithmeticExpression)
}
let four = ArithmeticExpression.number(4)
let five = ArithmeticExpression.number(5)
let sum = ArithmeticExpression.add(four, five)
print("sum is \(sum)")
let multiply = ArithmeticExpression.multiply(sum, ArithmeticExpression.number(2))
print(multiply)

//在函数中根据switch语句获取匹配的case条件
func eval(_ expression: ArithmeticExpression) -> Int {
    switch expression {
    case .number(let value):
        return value
    case .add(let first, let second):
        return eval(first) + eval(second)
    case .multiply(let first, let second):
        return eval(first) * eval(second)
}
}
print(eval(multiply))
